package com.arrogames.blondbattle.game.ai 
{
	import ash.core.Engine;
	import ash.core.NodeList;
	import ash.tools.ListIteratingSystem;
	import com.arrogames.blondbattle.game.EntityCreator;
	import com.arrogames.blondbattle.game.state.CommanderNode;
	import com.arrogames.blondbattle.game.purchases.CooldownNode;
	import com.arrogames.blondbattle.game.combat.Faction;
	import com.arrogames.blondbattle.model.UnitDefinition;
	import feathers.data.ListCollection;
	
	import org.as3commons.logging.api.getLogger;
	import org.as3commons.logging.api.ILogger;
	
	/**
	 * ...
	 * @author A.J. van Steenwijk
	 */
	public class AISystem extends ListIteratingSystem 
	{
		private var creator:EntityCreator;
		private var availableUnits:ListCollection;
		private var cooldownNodes:NodeList;
		private var minimalUnitValue:Number = 0;
		
		private static const logger:ILogger = getLogger(AISystem);
		
		public function AISystem(pCreator:EntityCreator, pAvailableUnits:ListCollection) 
		{
			this.creator = pCreator;
			this.availableUnits = pAvailableUnits;
			//set the minimal costs to ensure that the AI wont try to buy something while the money is insufficient.
			minimalUnitValue = (availableUnits.getItemAt(0) as UnitDefinition).costs;
			var unit:UnitDefinition = null;
			for (var i:int = 0; i < availableUnits.length; i++ ) {
				unit = availableUnits.getItemAt(i) as UnitDefinition;
				if ( unit.costs < minimalUnitValue) {
					minimalUnitValue = unit.costs;
				}
			}
			super(CommanderNode, updateNode);
		}
		
		override public function addToEngine( engine : Engine ) : void
		{
			super.addToEngine(engine);
			cooldownNodes = engine.getNodeList( CooldownNode );
		}

		
		private function updateNode(node:CommanderNode, time:Number) : void
		{
			//check if we are dealing with the AI faction commander
			if (node.faction.name == Faction.COMPUTER) {
				var money:Number = node.money.value;
				if (money >= minimalUnitValue) {
					var unit:UnitDefinition = getUnitDefinitionForMoney(money);
					if (null != unit ) {
						logger.debug('ordering unit: ' + unit.name);
						creator.createUnitOrder(unit, node.faction);
					}
				}
			}
		}
		
		private function getUnitDefinitionForMoney(pAvailableMoney:Number) : UnitDefinition
		{
			var unitToBuy:UnitDefinition = null;
			var unit:UnitDefinition = null;
			for (var i:int = 0; i < availableUnits.length; i++ ) {
				unit = availableUnits.getItemAt(i) as UnitDefinition;
				//check which unit we can purchase
				if ( unit.costs <= pAvailableMoney && isCooldownExpired(unit)) {
					logger.debug("can purchase unit: " +  unit.name);
					unitToBuy = unit;
					break;
				}
			}
			return unitToBuy;
		}
		
		/**
		 * Check if the cooldown has expired for the requested unit
		 * @param	unit	UnitDefinition
		 * @return	Boolean
		 */
		private function isCooldownExpired(unit:UnitDefinition) : Boolean
		{
			var cooldownExpired:Boolean = true;
			for( var node : CooldownNode = cooldownNodes.head; node; node = node.next )
			{
				if (node.faction.name == Faction.COMPUTER && node.unit.name == unit.name) {
					cooldownExpired = false;
				}
			}
			return cooldownExpired;
		}
		
	}

}